package com.onpositive.notes.android.ui.elements;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import com.onpositive.businessdroids.model.IColumn;
import com.onpositive.businessdroids.model.IField;
import com.onpositive.businessdroids.model.IModelChangeListener;
import com.onpositive.businessdroids.model.TableModel;
import com.onpositive.businessdroids.model.aggregation.IAggregator;
import com.onpositive.businessdroids.model.impl.AbstractCollectionBasedModel;
import com.onpositive.businessdroids.model.impl.AbstractComputableField;
import com.onpositive.businessdroids.model.impl.BasicTableModel;
import com.onpositive.businessdroids.model.impl.Column;
import com.onpositive.businessdroids.ui.IOpenListener;
import com.onpositive.businessdroids.ui.IViewer;
import com.onpositive.businessdroids.ui.actions.ActionContribution;
import com.onpositive.businessdroids.ui.actions.IContributionItem;
import com.onpositive.businessdroids.ui.actions.IContributionItemProvider;
import com.onpositive.businessdroids.ui.dataview.DataViewFactory;
import com.onpositive.businessdroids.ui.dataview.StructuredDataView;
import com.onpositive.businessdroids.ui.dataview.renderers.IFieldRenderer;
import com.onpositive.businessdroids.ui.themes.BasicTheme;
import com.onpositive.notes.android.main.CommonResources;
import com.onpositive.notes.android.main.EditNoteActivity;
import com.onpositive.notes.android.tools.NoteRecordRenderer;
import com.onpositive.notes.impl.BasicNote;
import com.onpositive.notes.model.INote;
import com.onpositive.notes.services.BasicNoteRegistry;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;

public class NoteListUIExperiment {
	
	private StructuredDataView sdv;
	
	Column contentField ;
	Column dateField ;	
	
	public View createView( Context context ){
		
		
		
		LinearLayout lt = new LinearLayout( context ) ;
		lt.setOrientation(LinearLayout.VERTICAL) ;
		initDataView(context, lt) ;
		
		return lt ;
	}
	
	
	private void initColumns() {
		
		contentField = new Column( new AbstractComputableField() {

			@Override
			public Object getPropertyValue(Object object) {

				if (object == null)
					return "NULL";

				if (object instanceof INote)
					return object; //((INote) object).getInitialText() ;

				return object.toString();
			}
		} );

		dateField = new Column( new AbstractComputableField() {

			@Override
			public Object getPropertyValue(Object object) {

				if (object == null)
					return "NULL";

				if (object instanceof INote) {
					Date date = ((INote) object).getDate();
					SimpleDateFormat sdf =
							new SimpleDateFormat( "dd,MMMM,yyyy", CommonResources.defaultLocale ) ;
					
					String result = sdf.format(date);
					return result;
				}
				return object.toString();
			}
		} );
		
		contentField.setId("content") ;
		dateField.setId("date") ;
	}


	public View createView1( Context context ){
		
		initColumns() ;
		LinearLayout lt = new LinearLayout( context ) ;
		lt.setOrientation(LinearLayout.VERTICAL) ;
		initDataView(context, lt) ;
		
		patchDataView() ;
		
		return lt ;
	}
	
	private void patchDataView() {
		
		sdv.getViewRendererService().registerRenderer( contentField, new NoteRecordRenderer() ) ;

	}

	public void initDataView( final Context context, LinearLayout lt )
	{
		
		
		IField[] fields = new IField[]{ contentField , dateField } ;
		
		sdv = DataViewFactory.createTable(
				context, BasicNoteRegistry.getInstance().getAllNotes(), null, null, fields);
		
		sdv.setCurrentTheme( new BasicTheme() ) ;
		sdv.setActionBarVisible(true) ;
		sdv.setHeaderVisible(true) ;
		sdv.setFooterVisible(true) ;

//		sdv.setOpenListener(new IOpenListener() {
//
//			@Override
//			public void openElement(View parent, View elementView, Object element, int pos)
//			{
//				if( !(context instanceof Activity) )
//					return ;
//				
//				Activity activity = (Activity) context ;
//				INote note = (INote) element;
//
//				Intent intent = new Intent( activity, EditNoteActivity.class);
//				intent.putExtra(EXTRA_KEY_NOTE, note);
//				intent.putExtra(EXTRA_KEY_INDEX, pos);
//				activity.startActivityForResult(intent, REQUEST_EDIT_NOTE);
//			}
//		});
		sdv.getTableModel().addModelChangeListener( new IModelChangeListener() {
			
			@Override
			public void aggregatorChanged(IAggregator oldAggregator,
					IAggregator newAggregator, IColumn column) {}
			
			@Override
			public void modelChanged(TableModel model) {
				Collection<Object> content = ((AbstractCollectionBasedModel)sdv.getTableModel()).getContent();
				HashSet<Integer> presentNotes = new HashSet<Integer>() ;
				for( Object obj : content ){
					INote note = (INote) obj ;
					if( note.getId() < 0 )
						BasicNoteRegistry.getInstance().registerNote(note) ;
					
					presentNotes.add( note.getId() ) ;
				}
				
				List<INote> allNotes = BasicNoteRegistry.getInstance().getAllNotes();
				
				ArrayList<INote> toDelete = new ArrayList<INote>() ;				
				for( INote note : allNotes ){
					if( !presentNotes.contains( note.getId() ) )
						toDelete.add(note) ;
				}
				for( INote note : toDelete )
					BasicNoteRegistry.getInstance().unRegisterNote(note) ;
			}
		}) ;
		
		final Drawable addIcon = context.getResources().getDrawable( com.onpositive.notes.android.test.R.drawable.add) ;
		final Drawable deleteIcon = context.getResources().getDrawable( com.onpositive.notes.android.test.R.drawable.delete) ;
		sdv.setContributionItemProvider( new IContributionItemProvider() {
			
			ArrayList<IContributionItem> lst = new ArrayList<IContributionItem>(  Arrays.asList(
					new IContributionItem[]{new ActionContribution( "Add new note", addIcon ) {
						
						@Override
						protected void run() {
							BasicNote note = new BasicNote( null, null, new Date(System.currentTimeMillis()), "");
							ArrayList<INote> list = new ArrayList<INote>();
							list.add(note) ;
							((BasicTableModel)sdv.getTableModel()).addAll( list) ;
						}
					},
					new ActionContribution( "Delete note", deleteIcon ) {
						
						@Override
						protected void run() {
							
							TableModel tableModel = sdv.getTableModel();
							AbstractCollectionBasedModel tModel = (AbstractCollectionBasedModel) tableModel ;
							Object selected = tableModel.getSelectedRecord() ;							
							tModel.removeItem(selected) ;
							tModel.setSelectedRecord(null) ;
						}
					}})) ;
			
			@Override
			public List<IContributionItem> getContributionItemsFor(IColumn column) {
				return lst;
			}
			
			@Override
			public List<IContributionItem> getCommonContributionItems() {
				return lst;
			}
		}) ;
		
		lt.addView( sdv, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT) ) ;
		
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK && requestCode == UIConstants.REQUEST_EDIT_NOTE) {
			
			if( sdv == null )
				return ;
			
			Bundle extras = data.getExtras();
			if(extras == null)
				return ;

			if (!data.hasExtra(UIConstants.EXTRA_KEY_NOTE))
				return;
			
			INote newNote = (INote) extras.get(UIConstants.EXTRA_KEY_NOTE);
			AbstractCollectionBasedModel tableModel = (AbstractCollectionBasedModel)sdv.getTableModel();

			if (data.hasExtra(UIConstants.EXTRA_KEY_INDEX)) {
				int ind = extras.getInt(UIConstants.EXTRA_KEY_INDEX);
				Object oldNote = tableModel.getItem(ind);
				tableModel.removeItem(oldNote) ;
			}
			boolean delete = false ;
			if( data.hasExtra("delete") ){
				delete = data.getBooleanExtra("delete", false) ;
			}
			if(!delete)
				tableModel.addItem(newNote) ;
			//TODO synchronize changes here
		}
	}

}
